/*package Chapter8Test;

import java.awt.*;

public class Ball {
    int X,Y; //球的坐标
    Color ballColor;  //球的颜色
    final int ballSize=16; //球的大小
    double speedX,speedY;  //横向速度与纵向速度

    public Ball(int X, int Y, Color ballColor, double speedX, double speedY) {
        this.X = Y;
        this.Y = Y;
        this.ballColor = ballColor;
        this.speedX = speedX;
        this.speedY = speedY;
    }
}
package Yuan;

        import javax.swing.*;
        import java.awt.*;

public class BallFrame {
    public static void main(String[] arg){
        BallFrame bf = new BallFrame();
        bf.showUI();
    }

    private void showUI() {
        JFrame jf = new JFrame();
        jf.setName("小球V1");
        jf.setSize(500,600);
        jf.setDefaultCloseOperation(3);
        jf.setLocationRelativeTo(null);

        JPanel jp_control = new JPanel();
        JPanel jp_ball = new JPanel();
        jp_control.setBackground(Color.lightGray);
        jp_ball.setBackground(Color.white);
        jf.add(jp_control,BorderLayout.NORTH);
        jf.add(jp_ball,BorderLayout.CENTER);

        JButton jb  = new JButton("delay");
        jp_control.add(jb);

        jf.setVisible(true);

        Graphics g = jp_ball.getGraphics();
        ThreadListener threadListener = new ThreadListener(g,jp_ball);
        jp_ball.addMouseListener(threadListener);
        jb.addActionListener(threadListener);

    }

}
package Yuan;

        import javax.swing.*;
        import java.awt.*;
        import java.awt.event.ActionEvent;
        import java.awt.event.ActionListener;
        import java.awt.event.MouseAdapter;
        import java.awt.event.MouseEvent;
        import java.util.ArrayList;

public class ThreadListener extends MouseAdapter implements ActionListener {

    private int x,y;
    //JPanel：用于获取画笔的长和宽
    private JPanel jp_ball;
    //队列：存储球的对象，不用定义初始长度
    private ArrayList<Ball> listBall = new ArrayList<Ball>();
    //线程：线程中循环绘制listBall中的所有ball
    private BallThread ballThread;

    public ThreadListener(Graphics g,JPanel jp_ball) {
        this.jp_ball = jp_ball;
        //构造函数只使用1次，在此处创建线程，则线程一定只有一个——实现一个线程绘制多个小球
        //创建线程对象，构造方法将画笔和画布和队列listBall传入
        if(ballThread==null){
            System.out.println("线程创建");
            ballThread = new BallThread(g,listBall,jp_ball);
            ballThread.start();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("run");
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        // 1.获取x和y
        x = e.getX();
        y = e.getY();
        // 2.判断点击是否超出界面，超出则把其设置为边界x和y
        if (x + 20 >= jp_ball.getWidth()){
            x = jp_ball.getWidth() - 30;
        }
        if (y + 20 >= jp_ball.getHeight()){
            y = jp_ball.getHeight() - 30;
        }
        // 3.点击时，创建小球对象，
        Ball ball = new Ball(x,y);
        // 4.将小球对象存入小球队列listBall中
        listBall.add(ball);
    }
}
package Yuan;

        import java.awt.*;
        import javax.swing.*;
        import java.util.ArrayList;

public class BallThread extends Thread {

    private Graphics g;
    private JPanel jp_ball;
    private ArrayList<Ball> listBall;

    public BallThread(Graphics g,ArrayList<Ball> listBall,JPanel jp_ball){
        this.g = g;
        this.listBall = listBall;
        this.jp_ball = jp_ball;
    }

    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(100);
            } catch (Exception e) {
            }
            for (int i=0;i<listBall.size();i++){
                listBall.get(i).drawBall(g,jp_ball);
            }
        }

    }
}
package Yuan;

        import javax.swing.*;
        import java.awt.*;

public class Ball {
    private int x, y;
    private int r = 30;
    private int vx = 15, vy = 15;

    public Ball(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void drawBall(Graphics g, JPanel jp_ball) {
        //1.判断是否为边界
        if (x <= 0 || x + r >= jp_ball.getWidth()) {
            vx = -vx;
        }
        if (y <= 0 || y + r >= jp_ball.getHeight()) {
            vy = -vy;
        }
        //2.绘制一个背景色小球，覆盖于上次绘制的小球上
        g.setColor(Color.white);
        g.fillOval(x, y, r, r);
        //3.获取本次的x和y
        x += vx;
        y += vy;
        //4.绘制本次小球
        g.setColor(Color.orange);
        g.fillOval(x, y, r, r);
    }
}*/